﻿/****************************************************************************
** file: matUtils.h
** brief: cv::Mat 的一些常用功能代码
** Copyright (C) LiYuan
** Author: LiYuan
** E-Mail: 18069211#qq(.)com
** Version 2.0.1
** Last modified: 2021.01.25
** Modified By: LiYuan
****************************************************************************/

#ifndef MATUTILS_H
#define MATUTILS_H

#include <opencv2/core.hpp>


std::vector<cv::Vec3b> buildRandomColormap(int N);
/**
 * @brief imageFromColormap 将灰度图转换为彩色图
 * @param grayImage 灰度图
 * @param colormap，根据colormap 来做颜色映射
 * @return
 */
cv::Mat imageFromColormap(const cv::Mat &grayImage, const std::vector<cv::Vec3b> &colormap);

/**
 * @brief getEdgePoints 从图中提取出亮度大于 threshold 的点
 * @param contours
 * @param threshold
 * @return
 */
std::vector<cv::Point2i> getEdgePoints(cv::Mat &contours, int threshold);

/**
 * @brief drawContours 在 bgr 上将 contours 上的不为零的像素点填充为 color
 * @param bgr 要求是 3 通道的图像或者 4 通道图像
 * @param contours
 * @param color
 */
void drawContours(cv::Mat bgr, cv::Mat contours, cv::Vec3b color);

void drawPoints(cv::Mat img, std::vector<cv::Point2d> pts, cv::Scalar color);

void colorReduce(cv::Mat &image, int div=64);

/**
 * @brief mat32Fto8U 将 Float 型图像转化为 8bits 图像
 * @param in float 型图像，每个像素通道的取值范围通常为 0-1
 * @param out  8bits 图像
 * @param alpha 放缩系数  输出图像的每个像素通道的值为 alpha * x + beta， x 为输入图像的像素值
 * @param beta 平移系数
 * @return
 */
bool mat32Fto8U(const cv::Mat &in, cv::Mat &out, double alpha = 255.0, double beta = 0.0);

/**
 *  \brief 增强图像的对比度。
 *  
 *  \param [in] in 输入图像
 *  \param [in] out 输出图像
 *  \return true 表示成功
 *  
 *  \details 通过将颜色值拉到值域最大范围增加对比度
 */
bool contrastEnhance(const cv::Mat &in, cv::Mat &out);

void salt(cv::Mat &image, int N);

void sharpen2D(const cv::Mat &image, cv::Mat &result);

/**
 * @brief colorImage2GrayImage 将彩色图像转换为灰度图像
 * @param inImage 输入的彩色图像
 * @param outImage 输出的灰度图像
 * @return true 表示转换成功，false 则表示转换失败
 */
bool colorImage2GrayImage(const cv::Mat &inImage, cv::Mat &outImage);


/**
 * @brief detectHSColor 提取图像中具有特定颜色范围的区域，图像是3 通道 BGR 图像
 * @param image 输入图像，要求是 3 通道 BGR 图像
 * @param minHue  Hue 的最小值，Hue 范围 0-179 （Hue本质是个角度，在0-360之间，OpenCV 用 0-180 表示。0表示红色。）
 * @param maxHue  Hue 的最大值，Hue 范围 0-179
 * @param minSat Sat 的最小值，Sat 范围 0-255
 * @param maxSat Sat 的最大值，Sat 范围 0-255
 * @param mask 提取出的区域
 */
void detectHSColor(const cv::Mat &image,
                   double minHue, double maxHue,
                   double minSat, double maxSat,
                   cv::Mat &mask);
#endif // MATUTILS_H
